package cn.tedu.charging.device.dao.repository.impl;

import cn.tedu.charging.device.dao.repository.AbstractStationCacheRepository;
import cn.tedu.charging.device.dao.repository.StationCacheRepository;
import cn.tedu.charging.device.pojo.po.StationCanalPO;
import cn.tedu.charging.device.pojo.po.StationPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 独享 一个站 一个map
 * Map<BigKey,Map<hashKey,value>>
 *
 * BigKey  stationId
 * hashKey 站的属性名 stationName
 * value   站的属值  充的快充电站
 *
 * Map<BigKey,Map<hashKey,value>> bigmap = map();
 * Map<hashKey,value> smallmap =map();
 *
 * smallmap.put("stationName","充的快充电站")
 * smallmap.put("status","营业中")
 * smallmap.put("gunNum","100")
 *
 * bigmap.put(1,smallmap)
 *
 * PO的属性 拆开 存到hash
 * Redis 的Hash
 *
 * 可以通过大key和hashKey 直接<获取>到 value   1  stationName  --> 充的快充电站 容易复用
 * 可以通过大key和hashKey 直接<修改>到 value   1  stationCode --> xxx  只修改一个字段
 *
 * 如果 站的数据量过大 redis 可以采用 分片技术 不同的站 在不同的分片   容易扩展
 *

 *
 *
 */
@Slf4j
@Repository("GeoAndNoShareHash")
public class StationCacheGeoAndNoShareHashRepositoryImpl
        extends AbstractStationCacheRepository
        implements StationCacheRepository {

    @Autowired
    private RedisTemplate redisTemplate;

    private static final String STATIONS_KEY = "stations_mapping";
    private static final String STATION_INFO_STR_KEY = "station_info_string_";

    @Override
    public void saveAllStations(List<StationPO> stations) {
        saveLocationByGEOAndMemberIsId(stations);
        saveStationInfo2NoShareHash(stations);
    }

    private void saveStationInfo2NoShareHash(List<StationPO> stations) {
        HashOperations hashOperations = redisTemplate.opsForHash();

        for (StationPO station : stations) {
            String bigKey = "station_info_hash_no_share_" + station.getId();
            String nameHashKey = "stationName";
            String lngHashKey = "lng";
            String latHashKey = "lat";

            Map<String,Object> smallMap = new HashMap<>();
            smallMap.put(nameHashKey,station.getStationName());
            smallMap.put(lngHashKey,station.getStationLng());
            smallMap.put(latHashKey,station.getStationLat());
            hashOperations.putAll(bigKey,smallMap);
        }

    }

    @Override
    public RedisTemplate getRedisTemplate() {
        return redisTemplate;
    }

    @Override
    public List<StationPO> search(Double lng, Double lat, Integer distance) {
        return super.search(lng, lat, distance);
    }

    @Override
    public void insert(StationCanalPO stationCanalPO) {
        //todo
    }

    @Override
    public void update(StationCanalPO before, StationCanalPO after) {
        //todo
    }

    @Override
    public void delete(StationCanalPO stationCanalPO) {
        //todo
    }

    @Override
    public StationPO getStationById(Integer stationId) {
        String bigKey = "station_info_hash_no_share_" + stationId;
        HashOperations hashOperations = redisTemplate.opsForHash();
        String nameHashKey = "stationName";
        String lngHashKey = "lng";
        String latHashKey = "lat";
        Map<String,Object> smallMap = hashOperations.entries(bigKey);
        Object stationName = smallMap.get(nameHashKey);
        Object lng = smallMap.get(lngHashKey);
        Object lat = smallMap.get(latHashKey);
        StationPO stationPO = new StationPO();
        BigDecimal bigDecimalLng = new BigDecimal(String.valueOf(lng));
        BigDecimal bigDecimalLat = new BigDecimal(String.valueOf(lat));
        stationPO.setId(stationId);
        stationPO.setStationName(String.valueOf(stationName));
        stationPO.setStationLng(bigDecimalLng);
        stationPO.setStationLat(bigDecimalLat);
        return stationPO;
    }
}
